package com.billionsfinance.hessian.core;


import com.billionsfinance.hessian.common.anno.HessianPath;
import com.billionsfinance.hessian.mapper.ServerInfoMapper;
import com.billionsfinance.hessian.model.ServerInfo;
import org.apache.commons.lang3.time.StopWatch;
import org.apache.ibatis.session.SqlSession;
import org.reflections.Reflections;

import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
 * @fileName: HessianServerInitFactory.java
 * @author: WeiHui.Zhang
 * @date: 2016-08-04  14:16
 * @version: v1.0.0
 */
public class HessianServerInitFactory extends HessianInitFactory {

	@Override
	protected void initHessianData() {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		ServerInfoMapper mapper = sqlSession.getMapper(ServerInfoMapper.class);
		if (autoInsert) {
			mapper.deleteAll();
			sqlSession.commit(true);
			autoInsertHessianData(mapper);
			sqlSession.commit(true);
		}
		loadToMemory(mapper.findAll());
		sqlSession.close();
	}

	/**
	 * 插入Hessian数据
	 */
	private void autoInsertHessianData(ServerInfoMapper mapper) {
		StopWatch watch = new StopWatch();
		watch.start();
		if (servicePackages == null || serviceImplPackages == null) {
			throw new IllegalArgumentException("Hessian客户端，Hessian接口包名 servicePackages 和 实现包名 serviceImplPackages 尚未配置。");
		}
		LOGGER.info("初始化Hessian信息到数据库开始！扫描接口包路径:{},实现包路径:{}", Arrays.asList(servicePackages), Arrays.asList(serviceImplPackages));
		int i = 0;
		Reflections reflections = new Reflections(servicePackages);
		Set<Class<?>> services = reflections.getTypesAnnotatedWith(HessianPath.class);
		for (Class<?> clazz : services) {
			if (!clazz.isInterface()) {
				String serviceClassName = clazz.getName();
				Class<?> service = clazz.getInterfaces()[0];
				String accessPath = service.getSimpleName();
				// 保存hessian服务端数据
				ServerInfo info = new ServerInfo();
				info.setAppCode(appCode);
				info.setAccessPath(accessPath);
				info.setInterfaceName(service.getName());
				info.setServiceClassName(serviceClassName);
				info.setCreateBy(createBy);
				info.setUpdateBy(createBy);

				mapper.insert(info);
				i++;
			}
		}
		watch.stop();
		LOGGER.info("初始化Hessian信息到数据库结束，耗时:{}ms,服务端表插入:{}条数据。", watch.getTime(), i);
	}

	/**
	 * 加载Hessian数据到内存
	 *
	 * @param serverInfos hessian服务端信息列表
	 */
	private void loadToMemory(List<ServerInfo> serverInfos) {
		for (ServerInfo serverInfo : serverInfos) {
			LOGGER.info("serverInfo detail: {}", serverInfo);
			HessianCacheManager.setServerInfo(serverInfo.getAccessPath(), serverInfo);
		}
	}

}